/*
Copyright (C) 2008 raohmaru <http://www.raohmaru.com>

This file is part of Raohmaru AS3 Framework.

Raohmaru AS3 Framework is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Raohmaru AS3 Framework is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License
along with Raohmaru AS3 Framework.  If not, see <http://www.gnu.org/licenses/>.
*/

package jp.raohmaru.effects 
{
import flash.filters.BitmapFilter;
import flash.filters.ColorMatrixFilter;
import flash.display.DisplayObject;

/**
 * Conjunto de utilidades utilizadas por la clase jp.raohmaru.effects.ColorModifier.
 * @see ColorModifier
 * @author raohmaru
 * @version 1.0
 */
public class EffectUtil 
{
	/**
	 * Obtiene el índice de una clase del paquete flash.filters dentro de la matriz <code>filters</code> del objeto DisplayObject. Si no no encuentra ningún
	 * objeto BitmapFilter cuya clase coincida, devuelve <code>-1</code>.
	 * @param target Objeto de visualización del que obtener el índice
	 * @param filterClass Objeto Class a buscar dentro de la matriz <code>DisplayObject.filters</code>
	 * @return El índice del resultado
	 * @see flash.display.DisplayObject#filters
	 * @example
	<listing version="3.0">
	import flash.display.Shape;
	import flash.filters.ColorMatrixFilter;
	import flash.filters.BlurFilter;
	import jp.raohmaru.effects.EffectUtil;
	
	var child:Shape = new Shape();
		child.graphics.beginFill(0xFFCC00);
		child.graphics.drawCircle(100, 100, 100);
		child.graphics.endFill();
	addChild(child);
	
	child.filters = [new ColorMatrixFilter()];
	
	trace( EffectUtil.getFilterIndex(child, ColorMatrixFilter) ); // 0
	trace( EffectUtil.getFilterIndex(child, BlurFilter) ); // -1</listing>
	 */
	public static function getFilterIndex(target : DisplayObject, filterClass : Class) : int
	{
		for (var i:int=0; i<target.filters.length; i++)
		{
			if(target.filters[i] is filterClass)
				return i;
		}
		
		return -1;
	}

	/**
	 * Obtiene el primer objeto del tipo BitmapFilter dentro de la matriz <code>filters</code> del objeto DisplayObject que coincida con la clase especificada.
	 * Si no hay ninguna coincidencia, se obtendrá <code>null</code>
	 * @param target Objeto de visualización del que obtener el objeto BitmapFilter
	 * @param filterClass Objeto Class a buscar dentro de la matriz <code>DisplayObject.filters</code>
	 * @return Un objeto BitmapFilter o <code>null</code> en caso de no encontrar nada
	 * @see flash.filters.BitmapFilter
	 */
	public static function getBitmapFilter(target : DisplayObject, filterClass : Class) : BitmapFilter
	{
		var ind : int = getFilterIndex(target, filterClass);
		
		return	(ind > -1) ? target.filters[ind] : null;
	}
	
	/**
	 * Obtiene la propiedad <code>matrix</code> del primer objeto ColorMatrixFilter que se halle dentro de la matriz <code>filters</code> del objeto DisplayObject.
	 * Si no no encuentra ningún objeto ColorMatrixFilter, se obtendrá una matriz con los 20 valores por defecto que componen la propiedad <code>ColorMatrixFilter.matrix</code>.
	 * @param target Objeto de visualización del que obtener la matriz
	 * @return Una referencia a <code>ColorMatrixFilter.matrix</code> o una nueva matriz
	 * @see flash.filters.ColorMatrixFilter#matrix
	 * @see #getEmptyColorMatrix()
	 */
	public static function getColorMatrix(target : DisplayObject) : Array
	{
		var filter : BitmapFilter = getBitmapFilter(target, ColorMatrixFilter);
		
		return (filter) ? ColorMatrixFilter(filter).matrix : getEmptyColorMatrix();
	}
	
	/**
	 * Obtiene una matriz de 20 valores, para utilizar con la propiedad <code>ColorMatrixFilter.matrix</code>. El conjunto de valores es el que por defecto tiene
	 * cualquier objeto ColorMatrixFilter: 
	 * <pre>
	 * 1 0 0 0 0
	 * 0 1 0 0 0
	 * 0 0 1 0 0
	 * 0 0 0 1 0
	 * </pre>
	 * @return Una nueva matriz
	 * @see flash.filters.ColorMatrixFilter#matrix
	 */
	public static function getEmptyColorMatrix() : Array
	{
		return [1,	0,	0,	0, 0,
				0,	1,	0,	0, 0,
				0,	0,	1,	0, 0,
				0,	0,	0,	1, 0];
	}
	
	/**
	 * Establece un objeto BitmapFilter en la matriz <code>filters</code> del objetivo especificado. Si ya existe un objeto de la misma clase que
	 * <code>filter</code>, se reemplazará. En caso contrario, añadira el nuevo filtro al final de la matriz <code>filters</code>.
	 * @param target Objeto de visualización al que aplicar el filtro
	 * @param filter Objeto BitmapFilter a añadir
	 * @see flash.display.DisplayObject#filters
	 * @example
	<listing version="3.0">
	import flash.display.Shape;
	import flash.filters.BlurFilter;
	import flash.filters.DropShadowFilter;
	import jp.raohmaru.effects.EffectUtil;
	
	var child:Shape = new Shape();
		child.graphics.beginFill(0xFFCC00);
		child.graphics.drawCircle(100, 100, 100);
		child.graphics.endFill();
	addChild(child);
	
	child.filters = [new BlurFilter()];
	EffectUtil.setFilter(child, new BlurFilter(20, 20));
	trace(child.filters.length); // 1
	
	EffectUtil.setFilter(child, new DropShadowFilter(15));
	trace(child.filters.length); // 2</listing>
	 */
	public static function setFilter(target : DisplayObject, filter : BitmapFilter) : void
	{
		var ind : int = getFilterIndex(target, Class(Object(filter).constructor)),
			filters : Array = target.filters;

		if(ind > -1)
			filters[ind] = filter;
		else
			filters.push(filter);
			
		target.filters = filters;
	}

	/**
	 * Elimina un objeto BitmapFilter de la matriz <code>filters</code> del objeto DisplayObject que coincida con la clase especificada.
	 * @param target Objeto de visualización del que eliminar un filtro
	 * @param filterClass Objeto Class a buscar dentro de la matriz <code>DisplayObject.filters</code>
	 * @return Un objeto BitmapFilter o <code>null</code> en caso de fallar la eliminación
	 * @see flash.display.DisplayObject#filters
	 */
	public static function removeFilter(target : DisplayObject, filterClass : Class) : BitmapFilter
	{
		var ind : int = getFilterIndex(target, filterClass),
			filter : BitmapFilter;

		if(ind > -1)
		{
			var filters : Array = target.filters;
			filter = filters.splice(ind, 1)[0];			
			target.filters = filters;
		}
		
		return filter;
	}
}
}